package com.ynet.middleground.contract.policy;

import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.deepoove.poi.render.compute.RenderDataCompute;
import com.google.common.base.Throwables;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;

/**
 * @author liulx
 * @description 定义 SpringEL 表达式，匹配 Map
 * @date 2020-04-30 16:07
 */
public class SpELRenderDataCompute implements RenderDataCompute {

    ExpressionParser parser;
    EvaluationContext context;

    public SpELRenderDataCompute(Object root) {
        parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext(root);
        context.addPropertyAccessor(new MapAccessor());
        this.context = context;
    }

    @Override
    public Object compute(String el) {
        // mark: 无法计算或者读取表达式，会直接抛异常
        try {
            return parser.parseExpression(el).getValue(context);
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "无法计算或者读取模板参数表达式, case: {}",
                Throwables.getStackTraceAsString(e));
            throw new BusinessException("请检查参数:" + el, "ECCT0206");
        }
    }

}
